/**
 * 数组工具函数
 */

/**
 * 数组去重
 * @param {Array} arr - 数组
 * @returns {Array} 去重后的数组
 */
export function unique(arr) {
  if (!Array.isArray(arr)) {
    return [];
  }
  return [...new Set(arr)];
}

/**
 * 数组去重（根据指定属性）
 * @param {Array} arr - 数组
 * @param {string} key - 属性名
 * @returns {Array} 去重后的数组
 */
export function uniqueBy(arr, key) {
  if (!Array.isArray(arr)) {
    return [];
  }
  if (!key) {
    return unique(arr);
  }

  const seen = new Set();
  return arr.filter(item => {
    const value = item[key];
    if (seen.has(value)) {
      return false;
    }
    seen.add(value);
    return true;
  });
}

/**
 * 数组分组
 * @param {Array} arr - 数组
 * @param {Function|string} key - 分组键或函数
 * @returns {Object} 分组后的对象
 */
export function groupBy(arr, key) {
  if (!Array.isArray(arr)) {
    return {};
  }

  return arr.reduce((groups, item) => {
    const groupKey = typeof key === 'function' ? key(item) : item[key];
    if (!groups[groupKey]) {
      groups[groupKey] = [];
    }
    groups[groupKey].push(item);
    return groups;
  }, {});
}

/**
 * 数组排序
 * @param {Array} arr - 数组
 * @param {string} key - 排序键
 * @param {string} order - 排序方向 'asc' | 'desc'
 * @returns {Array} 排序后的数组
 */
export function sortBy(arr, key, order = 'asc') {
  if (!Array.isArray(arr)) {
    return [];
  }

  return [...arr].sort((a, b) => {
    const aVal = key ? a[key] : a;
    const bVal = key ? b[key] : b;

    if (aVal < bVal) {
      return order === 'asc' ? -1 : 1;
    }
    if (aVal > bVal) {
      return order === 'asc' ? 1 : -1;
    }
    return 0;
  });
}

/**
 * 数组分页
 * @param {Array} arr - 数组
 * @param {number} page - 页码（从1开始）
 * @param {number} size - 每页大小
 * @returns {Object} 分页结果
 */
export function paginate(arr, page = 1, size = 10) {
  if (!Array.isArray(arr)) {
    return { data: [], total: 0, page, size, totalPages: 0 };
  }

  const total = arr.length;
  const totalPages = Math.ceil(total / size);
  const start = (page - 1) * size;
  const end = start + size;
  const data = arr.slice(start, end);

  return {
    data,
    total,
    page,
    size,
    totalPages,
  };
}

/**
 * 数组扁平化
 * @param {Array} arr - 数组
 * @param {number} depth - 扁平化深度
 * @returns {Array} 扁平化后的数组
 */
export function flatten(arr, depth = Infinity) {
  if (!Array.isArray(arr)) {
    return [];
  }
  if (depth === 0) {
    return arr;
  }

  return arr.reduce((flat, item) => {
    return flat.concat(Array.isArray(item) ? flatten(item, depth - 1) : item);
  }, []);
}

/**
 * 数组交集
 * @param {Array} arr1 - 数组1
 * @param {Array} arr2 - 数组2
 * @returns {Array} 交集数组
 */
export function intersection(arr1, arr2) {
  if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
    return [];
  }
  return arr1.filter(item => arr2.includes(item));
}

/**
 * 数组差集
 * @param {Array} arr1 - 数组1
 * @param {Array} arr2 - 数组2
 * @returns {Array} 差集数组
 */
export function difference(arr1, arr2) {
  if (!Array.isArray(arr1) || !Array.isArray(arr2)) {
    return arr1 || [];
  }
  return arr1.filter(item => !arr2.includes(item));
}

/**
 * 数组并集
 * @param {Array} arr1 - 数组1
 * @param {Array} arr2 - 数组2
 * @returns {Array} 并集数组
 */
export function union(arr1, arr2) {
  if (!Array.isArray(arr1) && !Array.isArray(arr2)) {
    return [];
  }
  if (!Array.isArray(arr1)) {
    return arr2;
  }
  if (!Array.isArray(arr2)) {
    return arr1;
  }
  return unique([...arr1, ...arr2]);
}

/**
 * 数组随机打乱
 * @param {Array} arr - 数组
 * @returns {Array} 打乱后的数组
 */
export function shuffle(arr) {
  if (!Array.isArray(arr)) {
    return [];
  }
  const newArr = [...arr];
  for (let i = newArr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [newArr[i], newArr[j]] = [newArr[j], newArr[i]];
  }
  return newArr;
}

/**
 * 数组求和
 * @param {Array} arr - 数组
 * @param {string|Function} key - 求和键或函数
 * @returns {number} 求和结果
 */
export function sum(arr, key) {
  if (!Array.isArray(arr)) {
    return 0;
  }

  return arr.reduce((total, item) => {
    const value = key
      ? typeof key === 'function'
        ? key(item)
        : item[key]
      : item;
    return total + (Number(value) || 0);
  }, 0);
}

/**
 * 数组平均值
 * @param {Array} arr - 数组
 * @param {string|Function} key - 求平均键或函数
 * @returns {number} 平均值
 */
export function average(arr, key) {
  if (!Array.isArray(arr) || arr.length === 0) {
    return 0;
  }
  return sum(arr, key) / arr.length;
}
